package modelo.bd.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import modelo.bd.ConexionPool;
import modelo.bd.excepcion.DAOException;
import modelo.dominio.Paso;
import modelo.servicio.Flujos;

public class PasoDAO {

    private String query;

    public void add(Paso entity, String usuario) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        PreparedStatement invalidaFlujo = null;
        try {
            query = "INSERT INTO sil_pasos_flujo (pafl_fluj_clave, pafl_clave, pafl_descripcion, \n"
                    + "                             pafl_desc_corta,pafl_aviso, pafl_tipo_paso, pafl_monto_aprobacion, \n"
                    + "                             pafl_final_correcto, pafl_usuario_creo, pafl_fecha_creo) \n"
                    + "VALUES('" + entity.getFlujo().getClave().replace("'", "''")
                    + "', '" + entity.getClave()
                    + "', '" + entity.getDescripcion()
                    + "', '" + entity.getDescripcionCorta()
                    + "', '" + (entity.isAvisable() ? "S" : "N")
                    + "', '" + entity.getTipoPaso()
                    + "', " + entity.getMontoAprobacion()
                    + ", '" + (entity.isFinalCorrecto() ? "S" : "N")
                    + "', '" + usuario + "', SYSDATE)";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
            invalidaFlujo = conexion.prepareStatement(
                    invalidarFlujo(entity.getFlujo().getClave().replace("'", "''"),
                    usuario));
            invalidaFlujo.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("Error PADA-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (invalidaFlujo != null) {
                    invalidaFlujo.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error PADA-SQL " + ex.getMessage());
            }
        }
    }

    public void deleteWhere(String condition) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            query = "DELETE sil_pasos_flujo \n"
                    + "WHERE  " + condition;
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("Error PADD-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error PADD-SQL " + ex.getMessage());
            }
        }
    }

    public void update(Paso entity, String usuario) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        PreparedStatement invalidaFlujo = null;
        try {
            query = "UPDATE sil_pasos_flujo \n"
                    + "SET    pafl_descripcion        = '" + entity.getDescripcion() + "', \n"
                    + "       pafl_desc_corta         = '" + entity.getDescripcionCorta() + "', \n"
                    + "       pafl_aviso              = '" + (entity.isAvisable() ? "S" : "N") + "', \n"
                    + "       pafl_tipo_paso          = '" + entity.getTipoPaso() + "' , \n"
                    + "       pafl_monto_aprobacion   = " + entity.getMontoAprobacion() + ", \n"
                    + "       pafl_final_correcto     = '" + (entity.isFinalCorrecto() ? "S" : "N") + "', \n"
                    + "       pafl_usuario_modif      = '" + usuario + "', \n"
                    + "       pafl_fecha_modif        = SYSDATE \n"
                    + "WHERE  pafl_clave              = '" + entity + "' \n"
                    + "AND    pafl_fluj_clave         = '" + entity.getFlujo().getClave().replace("'", "''") + "'";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
            invalidaFlujo = conexion.prepareStatement(
                    invalidarFlujo(entity.getFlujo().getClave().replace("'", "''"),
                    usuario));
            invalidaFlujo.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("Error PADU-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (invalidaFlujo != null) {
                    invalidaFlujo.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error PADU-SQL " + ex.getMessage());
            }
        }
    }

    protected List<Paso> select() throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        ResultSet resultado = null;
        List<Paso> resultados = null;
        try {
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            resultado = sentencia.executeQuery();
            resultados = new ArrayList<Paso>();
            while (resultado.next()) {
                Paso paso = new Paso();
                paso.setClave(resultado.getString("clave"));
                paso.setFlujo(Flujos.instancia().porClave(resultado.getString("flujo")));
                paso.setDescripcion(resultado.getString("descripcion"));
                paso.setDescripcionCorta(resultado.getString("descripcion_corta") == null
                        ? ""
                        : resultado.getString("descripcion_corta"));
                paso.setAvisable(resultado.getString("avisable").equalsIgnoreCase("S"));
                paso.setTipoPaso(resultado.getString("tipo_paso"));
                paso.setMontoAprobacion(resultado.getDouble("monto"));
                paso.setFinalCorrecto(resultado.getString("final_correcto").equalsIgnoreCase("S"));
                resultados.add(paso);
            }
        } catch (SQLException ex) {
            throw new DAOException("Error PADS-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error PADS-SQL " + ex.getMessage());
            }
        }
        return resultados;
    }

    public List<Paso> selectAll() throws DAOException {
        query = "SELECT pafl_clave              AS clave, \n"
                + "       pafl_fluj_clave         AS flujo, \n"
                + "       pafl_descripcion        AS descripcion, \n"
                + "       pafl_desc_corta         AS descripcion_corta, \n"
                + "       pafl_aviso              AS avisable, \n"
                + "       pafl_tipo_paso          AS tipo_paso, \n"
                + "       pafl_monto_aprobacion   AS monto, \n"
                + "       pafl_final_correcto     AS final_correcto, \n"
                + "       DECODE(pafl_tipo_paso, 'I', 1, 'M', 2, 'F', 3) AS orden \n"
                + "FROM   sil_pasos_flujo "
                + "ORDER  BY orden, pafl_clave";
        return select();
    }

    public List<Paso> selectWhere(String condition) throws DAOException {
        query = "SELECT pafl_clave              AS clave, \n"
                + "       pafl_fluj_clave         AS flujo, \n"
                + "       pafl_descripcion        AS descripcion, \n"
                + "       pafl_desc_corta         AS descripcion_corta, \n"
                + "       pafl_aviso              AS avisable, \n"
                + "       pafl_tipo_paso          AS tipo_paso, \n"
                + "       pafl_monto_aprobacion   AS monto, \n"
                + "       pafl_final_correcto     AS final_correcto, \n"
                + "       DECODE(pafl_tipo_paso, 'I', 1, 'M', 2, 'F', 3) AS orden \n"
                + "FROM   sil_pasos_flujo \n"
                + "WHERE  " + condition
                + " ORDER  BY orden, pafl_clave";
        return select();
    }

//    public List<Paso> selectSeguntoPaso(String flujo) throws DAOException {
//        this.setQuery("SELECT EVFL_PAFL_FLUJO         AS clave, \n"
//                + "       pafl_fluj_clave         AS flujo, \n"
//                + "       pafl_descripcion        AS descripcion, \n"
//                + "       pafl_desc_corta         AS descripcion_corta, \n"
//                + "       pafl_aviso              AS avisable, \n"
//                + "       pafl_tipo_paso          AS tipo_paso, \n"
//                + "       pafl_monto_aprobacion   AS monto \n"
//                + "FROM   sil_flujos, \n"
//                + "       sil_pasos_flujo, \n"
//                + "       sil_eventos_flujo \n"
//                + "WHERE  pafl_tipo_paso   = 'I' \n"
//                + "AND    fluj_clave       = '" + flujo + "' \n"
//                + "AND    evfl_pafl_origen = pafl_clave \n"
//                + "AND    evfl_fluj_clave  = fluj_clave \n"
//                + "AND    pafl_fluj_clave  = fluj_clave");
//        return select();
//    }
    private String invalidarFlujo(String clave, String usuario) {
        return "UPDATE sil_flujos \n"
                + "SET    fluj_usuario_modif = '" + usuario + "', \n"
                + "       fluj_estatus       = 'N', \n"
                + "       fluj_fecha_modif   = SYSDATE \n"
                + "WHERE  fluj_clave         = '" + clave + "'";
    }
}
